﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace Eniux.Windows.ThreeDEngine.Adorners
{
    /// <summary>
    /// 当执行缩放时，出现在屏幕中央的十字形图形
    /// </summary>
    public class RectangleAdorner : Adorner
    {
        #region 常量、字段

        /// <summary>
        /// 十字形末梢长度
        /// </summary>
        private readonly double crossHairSize;

        /// <summary>
        /// 笔
        /// </summary>
        private readonly Pen pen;

        /// <summary>
        /// 笔
        /// </summary>
        private readonly Pen pen2;

        #endregion

        #region 构造、析构

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="adornedElement">要被添加装饰器的UIElement</param>
        /// <param name="rectangle">矩形</param>
        /// <param name="color1">颜色1</param>
        /// <param name="color2">颜色2</param>
        /// <param name="thickness1">粗细1</param>
        /// <param name="thickness2">粗细2</param>
        /// <param name="crossHairSize"></param>
        public RectangleAdorner(
            UIElement adornedElement,
            Rect rectangle,
            Color color1,
            Color color2,
            double thickness1 = 1.0,
            double thickness2 = 1.0,
            double crossHairSize = 10)
            : this(adornedElement, rectangle, color1, color2, thickness1, thickness2, crossHairSize, DashStyles.Dash)
        {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="adornedElement">要被添加装饰器的UIElement</param>
        /// <param name="rectangle">矩形</param>
        /// <param name="color1">颜色1</param>
        /// <param name="color2">颜色2</param>
        /// <param name="thickness1">粗细1</param>
        /// <param name="thickness2">粗细2</param>
        /// <param name="crossHairSize">十字形末梢长度</param>
        /// <param name="dashStyle2">笔样式</param>
        public RectangleAdorner(
            UIElement adornedElement,
            Rect rectangle,
            Color color1,
            Color color2,
            double thickness1,
            double thickness2,
            double crossHairSize,
            DashStyle dashStyle2)
            : base(adornedElement)
        {
            Rectangle = rectangle;

            // http://www.wpftutorial.net/DrawOnPhysicalDevicePixels.html
            var m = PresentationSource.FromVisual(adornedElement).CompositionTarget.TransformToDevice;
            double dpiFactor = 1 / m.M11;

            pen = new Pen(new SolidColorBrush(color1), thickness1 * dpiFactor);
            pen2 = new Pen(new SolidColorBrush(color2), thickness2 * dpiFactor);
            pen2.DashStyle = dashStyle2;
            this.crossHairSize = crossHairSize;
        }

        #endregion

        #region 公共属性

        /// <summary>
        /// 获取或设置矩形
        /// </summary>
        public Rect Rectangle { get; set; }

        #endregion

        #region 方法

        /// <summary>
        /// 绘制
        /// </summary>
        /// <param name="dc"></param>
        protected override void OnRender(DrawingContext dc)
        {
            double halfPenWidth = pen.Thickness / 2;

            double mx = (Rectangle.Left + Rectangle.Right) / 2;
            double my = (Rectangle.Top + Rectangle.Bottom) / 2;
            mx = (int)mx + halfPenWidth;
            my = (int)my + halfPenWidth;

            var rect = new Rect(
                (int)Rectangle.Left + halfPenWidth,
                (int)Rectangle.Top + halfPenWidth,
                (int)Rectangle.Width,
                (int)Rectangle.Height);

            // Create a guidelines set
            /*GuidelineSet guidelines = new GuidelineSet();
            guidelines.GuidelinesX.Add(rect.Left + halfPenWidth);
            guidelines.GuidelinesX.Add(rect.Right + halfPenWidth);
            guidelines.GuidelinesY.Add(rect.Top + halfPenWidth);
            guidelines.GuidelinesY.Add(rect.Bottom + halfPenWidth);
            guidelines.GuidelinesX.Add(mx + halfPenWidth);
            guidelines.GuidelinesY.Add(my + halfPenWidth);
            
            dc.PushGuidelineSet(guidelines);*/
            dc.DrawRectangle(null, pen, rect);
            dc.DrawRectangle(null, pen2, rect);

            if (crossHairSize != 0)
            {
                dc.DrawLine(pen, new Point(mx, my - crossHairSize), new Point(mx, my + crossHairSize));
                dc.DrawLine(pen, new Point(mx - crossHairSize, my), new Point(mx + crossHairSize, my));
                dc.DrawLine(pen2, new Point(mx, my - crossHairSize), new Point(mx, my + crossHairSize));
                dc.DrawLine(pen2, new Point(mx - crossHairSize, my), new Point(mx + crossHairSize, my));
            }

            // dc.Pop();
        }

        #endregion
    }
}
